import cv2 as cv
import numpy as np

WINDOW_NAME = 'HSV Picker'


def create_callback(state: dict, key: str):
    return lambda value: state.update({key: value})


def setup_interface(state: dict):
    cv.namedWindow(WINDOW_NAME)

    cv.createTrackbar('H (0-179)', WINDOW_NAME, state['H'], 179, create_callback(state, 'H'))
    cv.createTrackbar('S (0-255)', WINDOW_NAME, state['S'], 255, create_callback(state, 'S'))
    cv.createTrackbar('V (0-255)', WINDOW_NAME, state['V'], 255, create_callback(state, 'V'))
    cv.createTrackbar('OFF/ON', WINDOW_NAME, state['switch'], 1, create_callback(state, 'switch'))


def hsv_to_bgr(h: int, s: int, v: int) -> list:
    hsv_pixel = np.uint8([[[h, s, v]]])
    bgr_pixel = cv.cvtColor(hsv_pixel, cv.COLOR_HSV2BGR)
    return bgr_pixel[0, 0].tolist()


def update_image(img: np.ndarray, state: dict):
    if state['switch']:
        color = hsv_to_bgr(state['H'], state['S'], state['V'])
        img[:] = color
    else:
        img[:] = 0


def main():
    state = {'H': 0, 'S': 0, 'V': 255, 'switch': 1}
    img = np.zeros((300, 512, 3), dtype=np.uint8)

    setup_interface(state)

    while True:
        update_image(img, state)
        cv.imshow(WINDOW_NAME, img)

        if cv.waitKey(1) == 27:
            break

    cv.destroyAllWindows()


if __name__ == '__main__':
    main()
